using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Magiq.Insert;
using Magiq.Behaviors;
using Magiq.Update;

namespace Magiq
{
    public static class MagiqExtensions
    {
        public static IUpdate<T> Set<T, TReturn>(this IEnumerable<T> self, Expression<Func<T, TReturn>> property,
                                                 TReturn value)
            where T : class
        {
            return self.Magiq().Set(property, value);
        }

        public static IUpdate<T> Set<T, TReturn>(this IEnumerable<T> self, Expression<Func<T, TReturn>> property,
                                                 Expression<Func<T, TReturn>> value) where T : class
        {
            return self.Magiq().Set(property, value);
        }

        public static int Delete<T>(this IEnumerable<T> self) where T : class
        {
            return self.Magiq().Delete();
        }

        public static int Delete<T>(this IQueryable<T> self, Expression<Func<T, bool>> where) where T : class
        {
            return self.Magiq().Delete(where);
        }

        public static IInsertBuilder<TSource, T> From<TSource, T>(this IEnumerable<T> self, IEnumerable<TSource> source)
            where T : class
        {
            return self.Magiq().From(source);
        }

        public static IQueryable<T> Query<T>(this IEnumerable<T> self) where T : class
        {
            if (self is IQueryable<T>)
                return (IQueryable<T>) self;

            return self.Magiq().Query();
        }

        public static IQueryable<T> Query<T>(this IEnumerable<T> self, Expression<Func<T, bool>> where) where T : class
        {
            return self.Magiq().Query(where);
        }

        public static IMagiq<T> Using<T>(this IEnumerable<T> self, IMagiqBehavior behavior) where T : class
        {
            return self.Magiq().Using(behavior);
        }

        public static IMagiq<T> Magiq<T>(this IEnumerable<T> self) where T : class
        {
            return new MagiqOperations<T>(self, global::Magiq.Magiq.BehaviorChain);
        }
    }
}